Skip to content

Conversation

poltorak
Copy link
Collaborator

@poltorak poltorak commented Sep 5, 2025

Centralize and Standardize Vitest Configurations

What Changed

  • New centralized configuration system: Created testing/test-setup-config package with a factory-based approach for generating Vitest configurations
  • Setup presets: Introduced modular setup file presets that can be composed for different test types (unit, integration, e2e)
  • Simplified configuration files: Refactored 6 existing Vitest config files to use the new centralized system, reducing them from verbose configurations to simple function calls

Benefits

  • Eliminates duplication: Removes repetitive boilerplate across multiple vitest config files
  • Ensures consistency: Standardizes test configurations, coverage settings, and setup files across all packages
  • Improves maintainability: Changes to test configuration defaults now only need to be made in one place
  • Better developer experience: New configs are more readable and easier to customize with sensible defaults and preset combinations

The new system provides createUnitConfig, createIntConfig, and createE2eConfig factory functions that automatically handle common configuration patterns while still allowing customization through override parameters.

Relates to first part of #1065

@github-actions github-actions bot added 📖 Project documentation improvements or additions to the project documentation 🔬 testing writing tests 🛠️ tooling labels Sep 5, 2025
Copy link

nx-cloud bot commented Sep 5, 2025

View your CI Pipeline Execution ↗ for commit 7008a48

Command Status Duration Result
nx code-pushup --nx-bail -- compare ✅ Succeeded 53s View ↗
nx code-pushup --nx-bail -- ✅ Succeeded 1m 2s View ↗
nx code-pushup --nx-bail -- print-config --outp... ✅ Succeeded 3m 48s View ↗

☁️ Nx Cloud last updated this comment at 2025-10-06 15:34:39 UTC

Copy link

pkg-pr-new bot commented Sep 5, 2025

Open in StackBlitz

@code-pushup/ci

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/ci@1107

@code-pushup/cli

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/cli@1107

@code-pushup/core

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/core@1107

@code-pushup/create-cli

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/create-cli@1107

@code-pushup/models

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/models@1107

@code-pushup/nx-plugin

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/nx-plugin@1107

@code-pushup/coverage-plugin

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/coverage-plugin@1107

@code-pushup/eslint-plugin

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/eslint-plugin@1107

@code-pushup/js-packages-plugin

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/js-packages-plugin@1107

@code-pushup/jsdocs-plugin

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/jsdocs-plugin@1107

@code-pushup/lighthouse-plugin

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/lighthouse-plugin@1107

@code-pushup/typescript-plugin

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/typescript-plugin@1107

@code-pushup/utils

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/utils@1107

@code-pushup/models-transformers

npm i https://pkg.pr.new/code-pushup/cli/@code-pushup/models-transformers@1107

commit: 7008a48

Copy link
Contributor

github-actions bot commented Sep 5, 2025

Code PushUp

🤨 Code PushUp report has both improvements and regressions – compared current commit 5a5fcfa with previous commit 33714e2.

🕵️ See full comparison in Code PushUp portal 🔍

🏷️ Categories

🏷️ Category ⭐ Previous score ⭐ Current score 🔄 Score change
Performance 🔴 36 🔴 33 ↓ −2.6
Updates 🟡 84 🟡 84 ↓ −0.2
Code coverage 🟡 90 🟡 90 ↓ −0.1
Security 🟡 56 🟡 56
Accessibility 🟢 92 🟢 92
Best Practices 🟢 100 🟢 100
SEO 🟡 61 🟡 61
Type Safety 🟢 100 🟢 100
Bug prevention 🟢 100 🟢 100
Miscellaneous 🟢 100 🟢 100
Code style 🟢 100 🟢 100
Documentation 🔴 24 🔴 24
👎 3 groups regressed, 👍 4 audits improved, 👎 4 audits regressed, 14 audits changed without impacting score

🗃️ Groups

🔌 Plugin 🗃️ Group ⭐ Previous score ⭐ Current score 🔄 Score change
Lighthouse Performance 🔴 36 🔴 33 ↓ −2.6
JS Packages NPM outdated dependencies 🟡 84 🟡 84 ↓ −0.2
Code coverage Code coverage metrics 🟡 90 🟡 90 ↓ −0.1

18 other groups are unchanged.

🛡️ Audits

🔌 Plugin 🛡️ Audit 📏 Previous value 📏 Current value 🔄 Value change
Lighthouse Total Blocking Time 🟥 1,640 ms 🟥 2,770 ms ↑ +69.2 %
Lighthouse First Contentful Paint 🟥 3.3 s 🟥 3.1 s ↓ −4.5 %
Lighthouse Speed Index 🟥 7.2 s 🟥 7.6 s ↑ +6.1 %
Code coverage Line coverage 🟨 86.3 % 🟨 84.4 % ↓ −2.1 %
JS Packages Outdated NPM dev dependencies. 🟨 59 outdated package versions (27 major, 24 minor, 8 patch) 🟨 59 outdated package versions (28 major, 23 minor, 8 patch)  +0 %
Lighthouse Time to Interactive 🟥 13.6 s 🟥 13.3 s ↓ −2.2 %
Code coverage Function coverage 🟩 92.5 % 🟩 92.6 % ↑ +0.1 %
Code coverage Branch coverage 🟨 85.5 % 🟨 85.5 % ↑ +0.1 %
Lighthouse Avoids enormous network payloads 🟩 Total size was 2,039 KiB 🟩 Total size was 2,034 KiB ↓ −0.3 %
Lighthouse Minimizes main-thread work 🟥 11.9 s 🟥 14.4 s ↑ +21.6 %
Lighthouse JavaScript execution time 🟥 5.0 s 🟥 6.5 s ↑ +28.3 %
Lighthouse Uses efficient cache policy on static assets 🟨 30 resources found 🟨 30 resources found ↓ −0.1 %
Lighthouse Largest Contentful Paint 🟥 11.3 s 🟥 11.9 s ↑ +5.7 %
Lighthouse Max Potential First Input Delay 🟥 1,390 ms 🟥 1,890 ms ↑ +36.3 %
Lighthouse Metrics 🟩 100% 🟩 100% ↓ −2.2 %
Lighthouse Reduce unused CSS 🟥 Potential savings of 102 KiB 🟥 Potential savings of 102 KiB ↓ −32.6 %
Lighthouse Reduce unused JavaScript 🟥 Potential savings of 179 KiB 🟥 Potential savings of 180 KiB ↓ −15.4 %
Lighthouse Server Backend Latencies 🟩 1,540 ms 🟩 1,400 ms ↓ −8.9 %
Lighthouse Initial server response time was short 🟩 Root document took 600 ms 🟩 Root document took 470 ms ↓ −20.6 %
Lighthouse Network Round Trip Times 🟩 50 ms 🟩 10 ms ↓ −77.8 %
Lighthouse Remove duplicate modules in JavaScript bundles 🟥 Potential savings of 78 KiB 🟥 Potential savings of 99 KiB ↑ +3.3 %
JS Packages Vulnerabilities for NPM dev dependencies. 🟥 11 vulnerabilities (1 critical, 5 moderate, 5 low) 🟥 15 vulnerabilities (1 critical, 5 moderate, 9 low) ↑ +36.4 %

588 other audits are unchanged.

Copy link
Collaborator

@BioPhoton BioPhoton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for cleaning up our test config mess :)

I left some comments.

  • please add a proper PR description that contains the scope and planned changes
  • move the config code under a Nx project in testing/vitest-setup. I updated the issue accordingly.

@poltorak poltorak marked this pull request as ready for review September 10, 2025 06:45
Comment on lines 127 to 132
const testTimeout =
kind === 'unit'
? TEST_TIMEOUTS.MEDIUM
: kind === 'int'
? TEST_TIMEOUTS.LONG
: TEST_TIMEOUTS.E2E;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid conditionals in tests. It makes the test code harder to read and adds noise.

['unit', setupPresets.unit.base, createUnitConfig],
['int', setupPresets.int.base, createIntConfig],
['e2e', setupPresets.e2e.base, createE2eConfig],
] as const)('%s config creation', (kind, baseSetupFiles, createFn) => {
Copy link
Collaborator

@BioPhoton BioPhoton Oct 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The each block for describe is introducing conditional checks in the it blocks as well as const. It further makes the tests harder to read. Let's avoid conditionals in tests as good as possible.

If you want to test basic values you could have a separate it block using the each for static things like defaults that are always the same. In the specific cases you can use expect.objectContaining to keep is focused.

see example for conditionaly

export function createVitestConfig(
options: VitestConfigFactoryOptions,
overrides: VitestOverrides = {},
): ViteUserConfig {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest excluding overrides from the logic and push it to the user. This avoids complexity and reduces maintenance efforts to sync with vitest changes. WDYT @matejchalk

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please let me know which direction we should follow:

  • Easier override handling ( current solution ) - in this case we take care of most of the overrides but on the other hand we are exposed to vitest changes (if the happen) and we need to keep up it them
  • We go easy way and move transfer the "burden" of overrides to end consumer / user.

Both approaches have pros and cons. I don't feel like I'm the right person to make a decision here 😅

projectKey: string;
kind: TestKind;
projectRootUrl: URL;
cacheDirName: string;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could derive the cacheDirName from the projectKey. Internally if needed you can modify if needed e.g. cache-${projectKey}.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it suggestion or request change 😄 ?
Deriving cacheDirName from projectKey in form: cache-${projectKey} sounds ok but makes me wonder, aren't we making some hidden bond between project key and cache directory?

Maybe we could consider cacheDirName as optional which fallbacks to cache-${projectKey} if not specified?
Let me know @BioPhoton

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EDIT:
We already using such bond for coverage, let's do the same for cache. I'll update it

Copy link
Collaborator

@BioPhoton BioPhoton Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could consider cacheDirName as optional which fallbacks to ...

Yes better!

cache-${projectKey} if not specified?

the "cache-" was just something to give example. In general the cache key (and directory) should be unique across the repository. That is the reason we are about it in the first place.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method you highlighted in comment is kind of "internal", the fallback is done in line 50

Is that ok acceptable or do you suggest other approach to that?

Comment on lines 30 to 34
### Parameters

- `projectKey`: Used for cache and coverage directory naming
- `projectRoot`: Required path/URL to the project root for resolving all paths
- Standard Vitest configuration options can be provided in the overrides parameter
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is covered by the types. You could add TSDocs and remove it here.

Comment on lines 10 to 29
### Defaults

**Common**: `reporters: ['basic']`, `globals: true`, `environment: 'node'`, `pool: 'threads'` with `singleThread: true`, alias from tsconfig paths

**Coverage**: Unit/Int enabled (reports to `<projectRoot>/packages/<project>/.coverage`), E2E disabled. Excludes `['mocks/**', '**/types.ts']`

**Global setup**: Unit/Int use `['<projectRoot>/global-setup.ts']`, E2E none by default

**Include patterns**: Unit `src/**/*.unit.test.*`, Int `src/**/*.int.test.*`, E2E `tests/**/*.e2e.test.*`

### Setup files

**Automatic inclusion**: Unit (console mocking, cleanup, UI/filesystem mocks, basic matchers), Int (console mocking, cleanup), E2E (cleanup only)

**Custom setup files**: ⚠️ Specifying `setupFiles` in overrides will completely replace the defaults. To extend the default list, manually combine them with `setupPresets`:

- `setupPresets.unit.{base, git, portalClient, matchersCore, matcherPath}`
- `setupPresets.int.{base, cliui, fs, git, portalClient, matcherPath, chromePath}`
- `setupPresets.e2e.{base}`

Copy link
Collaborator

@BioPhoton BioPhoton Oct 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The defaults and setup files could be documented in unit tests. The example section could show the usage directly.

},
{
test: {
testTimeout: 60_000,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be a default for the e2e target

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked other files and there are many different values, like 20k, 40k, 80k, 60k, 120k.
Just making sure that we want to have 60k as default?

Copy link
Collaborator

@BioPhoton BioPhoton Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm.... I would put 20 as default. Or if there are more projects with 40 lets go with 40. And for the projects with higher or lower times go with a override.

Did not realise this is already an overwrite..

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked that and:

Timeout Occurences
20s 6
40s 1
60s 1
80s 2
120s 1

I suggest then use 20s as default (20_000ms)

Copy link
Collaborator

@BioPhoton BioPhoton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes! Nice testing tool! There is Readme, and tests, lovely.
I left some first comments and will wait for one feedback on the override logic for further comments.

@poltorak poltorak force-pushed the refactor/vitest-configurations branch from 9433ca5 to 7008a48 Compare October 6, 2025 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📖 Project documentation improvements or additions to the project documentation 🔬 testing writing tests 🛠️ tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants